﻿using Abp.Application.Services.Dto;
using Abp.Application.Services;
using Abp.Domain.Repositories;
using Choucius.Boilerplate9.PlasticContainers.Dto;
using Choucius.Boilerplate9.Enum;
using Choucius.Boilerplate9.PlasticContainerLogs;
using System;
using System.Threading.Tasks;
using System.Linq;
using Choucius.Boilerplate9.DtoBase;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;

namespace Choucius.Boilerplate9.PlasticContainers
{
    /// <summary>
    /// 吸塑盒
    /// </summary>
    public class PlasticContainerAppService : AsyncCrudAppService<PlasticContainer, PlasticContainerDto, Guid, PagedResultRequestDto, PlasticContainerDto, PlasticContainerDto>, IPlasticContainerAppService
    {
        private readonly IRepository<PlasticContainer, Guid> _repository;
        private readonly IRepository<PlasticContainerLog, long> _logRepository;

        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="logRepository"></param>
        public PlasticContainerAppService(IRepository<PlasticContainer, Guid> repository, IRepository<PlasticContainerLog, long> logRepository) : base(repository)
        {
            _repository = repository;
            _logRepository = logRepository;
        }

        /// <summary>
        /// 根据胶框ERP_ID获取最大值
        /// </summary>
        /// <param name="plasticContainerErpId">胶框ERP ID，8位数</param>
        /// <returns></returns>
        public async Task<int> GetMaxValueByRfidAsync(string plasticContainerErpId)
        {
            // 获取日期最大的。TODO：将来增加EPC序列号的int类型字段……
            var entity = await _repository.GetAll()
                        .Where(w => w.RFID.Substring(0, 8) == plasticContainerErpId)
                        .OrderByDescending(x => x.CreationTime)
                        .Take(1)
                        .FirstOrDefaultAsync();
            if (entity == null)
            {
                return 1;   // 如果没有，其实编号从1开始
            }
            string serial = entity.RFID.Length >= 8 ? entity.RFID.Substring(8) : "1";
            int i;
            int result = int.TryParse(serial, out i) ? i + 1 : 1;
            return result;
        }

        /// <summary>
        /// 根据RFID更新实体
        /// </summary>
        /// <param name="updateDto"></param>
        /// <returns></returns>
        public async Task UpdateEntityByRfidAsync(PlasticContainerDto updateDto)
        {
            var entity = await _repository.FirstOrDefaultAsync(x => x.RFID == updateDto.RFID);
            if (entity != null)
            {
                // 更新实体属性
                entity.EPC = updateDto.EPC;
                entity.Status = updateDto.Status;
                entity.NeedInunction = updateDto.NeedInunction;
                entity.PlasticContainerName = updateDto.PlasticContainerName;
                entity.WorkStationId = updateDto.WorkStationId;
                entity.RubberFrameId = updateDto.RubberFrameId;
                entity.LastModificationTime = DateTime.Now;
                entity.LastModifierUserId = updateDto.LastModifierUserId;
                await _repository.UpdateAsync(entity); // 确保你的 repository 支持 UpdateAsync 方法
            }
        }

        /// <summary>
        /// 根据RFID查询某一盒是否需要涂油
        /// </summary>
        /// <param name="rfid"></param>
        /// <returns></returns>
        public bool IsInunction(string rfid)
        {
            var entity = _repository.FirstOrDefault(x => x.RFID == rfid);
            if (entity == null)
            {
                return false;
            }
            return entity.NeedInunction;
        }


        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task BulkInsertItems(ImportDto dto)
        {
            foreach (var item in dto.PlasticContainers)
            {
                var newItem = new PlasticContainer
                {
                    RFID = item.RFID,
                    Status = item.Status,
                    CreationTime = DateTime.Now,
                    CreatorUserId = item.CreatorUserId
                };
                await _repository.InsertAsync(newItem);

                var newLog = new PlasticContainerLog
                {
                    RFID = item.RFID,
                    Status = item.Status,
                    CreationTime = DateTime.Now,
                    CreatorUserId = item.CreatorUserId
                };
                await _logRepository.InsertAsync(newLog);
            }
            //await _repository.SaveChangesAsync();
        }

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task BulkUpdateItems(ImportDto dto)
        {
            foreach (var item in dto.PlasticContainers)
            {
                var entity = _repository.GetAllList().FirstOrDefault(x => x.RFID == item.RFID);
                if (entity != null)
                {
                    entity.Status = item.Status;
                    entity.LastModifierUserId = item.LastModifierUserId;
                    entity.LastModificationTime = DateTime.Now;
                    _repository.Update(entity);

                    // 历史记录
                    var newLog = new PlasticContainerLog
                    {
                        RFID = item.RFID,
                        Status = item.Status,
                        CreationTime = DateTime.Now,
                        CreatorUserId = item.CreatorUserId
                    };
                    await _logRepository.InsertAsync(newLog);
                }
            }
        }

        /// <summary>
        /// 获取各个状态的吸塑盒数量
        /// </summary>
        /// <returns></returns>
        public PlasticContainerCountDto GetStatusCount()
        {
            var result = new PlasticContainerCountDto();
            result.Total = _repository.Count();
            result.Undefined = _repository.Count(x => x.Status == LabelStatus.Undefined);
            result.Initialization = _repository.Count(x => x.Status == LabelStatus.Initialization);
            result.InPackStock = _repository.Count(x => x.Status == LabelStatus.InPackStock);
            result.OutPackStock = _repository.Count(x => x.Status == LabelStatus.OutPackStock);
            result.InProductStock = _repository.Count(x => x.Status == LabelStatus.InProductStock);
            return result;
        }

        public async Task<Dictionary<LabelStatus, int>> StatisticByStatusAsync()
        {
            var query = from order in _repository.GetAll()
                        group order by order.Status into g
                        select new { Status = g.Key, Count = g.Count() };
            var result = await query.ToDictionaryAsync(x => x.Status, x => x.Count);
            return result;
        }

        public async Task<Dictionary<string, int>> InboundStatisticByPlasticContainerNameAsync()
        {
            var query = from order in _repository.GetAll()
                        where order.Status == LabelStatus.InPackStock
                        group order by order.PlasticContainerName into g
                        select new { PlasticContainerName = g.Key, Count = g.Count() };
            var result = await query.ToDictionaryAsync(x => x.PlasticContainerName, x => x.Count);
            return result;
        }
    }
}
